package bomberman.entity;

import gameframework.base.IntegerObservable;
import gameframework.base.Overlappable;
import gameframework.base.Drawable;
import gameframework.base.DrawableImage;
import gameframework.game.GameEntity;
import gameframework.game.GameMovable;

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;

import bomberman.BombermanGameLevel;


public class Bomberman extends GameMovable implements Drawable, GameEntity,
		Overlappable {
	public static final int SPRITE_WIDTH = 14;
	public static final int SPRITE_HEIGHT = 19;
	private static final int INVULNERABLE_TIME = 6;
	private static final int NUMBER_OF_BOMBS_TO_CATCH = 3;
	protected DrawableImage image = null;
	protected Canvas defaultCanvas;
	protected int spriteNumber = 0;
	protected int spriteType = 0;
	protected boolean movable = true;
	protected boolean vulnerable = false;
	
	private boolean canCatchBomb = false;

	private IntegerObservable bomb;
	//start power of bombs
	private int bombPower = 1;
	private int identity;
	private int invulnerableTimer;

	private boolean onBomb;

	//used to remember the position
	//of the last bomb dropped
	private Point bombPos = null;
	
	//number of bombs to catch
	private int numberOfBombsToCatch;
	
	//vomito bomb
	private int vomitoBomb = 0;

	public Bomberman(Canvas defaultCanvas,IntegerObservable bomb[], int identity) {
		if (image == null) {
			image = new DrawableImage("images/player"+(identity+1)+".png", defaultCanvas);
		}
		this.defaultCanvas = defaultCanvas;
		this.identity = identity;
		invulnerableTimer = INVULNERABLE_TIME;
		this.bomb = bomb[identity];
	}

	public void draw(Graphics g) {
		Point tmp = getSpeedVector().getDirection();
		movable = true;
		if (tmp.getX() == 1) {
			spriteType = 2;
		} else if (tmp.getX() == -1) {
			spriteType = 3;
		} else if (tmp.getY() == 1) {
			spriteType = 0;
		} else if (tmp.getY() == -1) {
			spriteType = 1;
		} else {
			movable = false;
		}
		g.drawImage(image.getImage(), (int) getPosition().getX(),
				(int) getPosition().getY(), (int) getPosition().getX()
						+ BombermanGameLevel.SPRITE_SIZE,
				(int) getPosition().getY() + BombermanGameLevel.SPRITE_SIZE, spriteNumber * SPRITE_WIDTH,
				spriteType * SPRITE_HEIGHT, (spriteNumber + 1) * SPRITE_WIDTH,
				(spriteType + 1) * SPRITE_HEIGHT, null);
	}

	public void dropBomb() {
		if(bomb.getValue() > 0 && !onBomb)
		{	
			//we get the bomberman's position
			int posX = (int) getPosition().getX(); 
			int posY = (int) getPosition().getY();
			if(posX%BombermanGameLevel.SPRITE_SIZE == 0 
					&& posY%BombermanGameLevel.SPRITE_SIZE == 0){
				BombermanGameLevel.medUniverse.getUniverse().addGameEntity(new Bomb(defaultCanvas,new Point(posX ,posY), 
					this, bombPower));

				onBomb = true;
				
				bombPos = (Point)getPosition().clone();
				vomitoBomb--;
				bomb.setValue(bomb.getValue() - 1);
			}
		}
	}

	@Override
	public void oneStepMoveHandler() {
		if (movable) {
			spriteNumber++;
			spriteNumber = spriteNumber % 3;
		}
		if(!vulnerable)
		{
			if(invulnerableTimer-- == 0)
			{
				vulnerable = true;
				invulnerableTimer = INVULNERABLE_TIME;
			}
		}
		
		if (bombPos == null || getPosition().getX() != bombPos.getX() ||
						getPosition().getY() != bombPos.getY())
			onBomb = false;

		if (vomitoBomb > 0)
			dropBomb();
	}

	public Rectangle getBoundingBox() {
		return (new Rectangle(0, 0, BombermanGameLevel.SPRITE_SIZE, BombermanGameLevel.SPRITE_SIZE));
	}
	
	public boolean isOnABomb(){
		return onBomb;
	}
	
	public void setOnBomb(boolean onBomb){
		this.onBomb = onBomb;
	}
	
	public int getIdentity() {
		return identity;
	}
	
	public void setVulnerable(boolean value) {
		vulnerable = value;
	}
	
	public boolean isVulnerable() {
		return vulnerable;
	}
	
	public void upBombPower(){
		bombPower++;
	}
	
	public void upNumberOfBombs(){
		bomb.setValue(bomb.getValue() + 1);
	}
	
	public void setCanCatchBomb(boolean val){
		canCatchBomb = val;
		numberOfBombsToCatch = NUMBER_OF_BOMBS_TO_CATCH;
	}
	
	public boolean canCatchBomb(){
		return canCatchBomb;
	}
	
	public Point getBombPos(){
		return bombPos;
	}
	
	public void vomitoBomb(){
		vomitoBomb = bomb.getValue();
	}
	
	public void decNumberOfBombsToCatch(){
		numberOfBombsToCatch--;
		if (numberOfBombsToCatch == 0)
			canCatchBomb = false;
	}
}
